package uriHandler

import (
	"bytes"
	"gitee.com/kaylee595/gkaylee/kerr"
	"gitee.com/kaylee595/m3u8/token"
	"io"
	"net/url"
	"strconv"
	"strings"
)

type resolveAbsoluteURL struct {
	r       *token.Decoder
	buf     []byte
	baseURL *url.URL
}

// NewResolveAbsoluteURL 该URI转换器会将非绝对的URL使用 baseURL 转为绝对的URL
func NewResolveAbsoluteURL(r io.Reader, baseURL *url.URL) io.Reader {
	return &resolveAbsoluteURL{
		r:       token.NewDecoder(r),
		baseURL: baseURL,
	}
}

var http = []byte("http")

func (r *resolveAbsoluteURL) Read(p []byte) (n int, err error) {
	if len(r.buf) > 0 {
		n = copy(p, r.buf)
		r.buf = r.buf[n:]
		return n, nil
	}
	line, err := r.r.ReadLine()
	if err != nil {
		return 0, kerr.WrapTraceStack(err)
	}
	kind := line.Kind()
	if kind == token.KindURI {
		if !bytes.HasSuffix(r.buf, http) { // 需要转绝对地址
			line = token.NewLineURI(r.baseURL.ResolveReference(&url.URL{Path: line.URI()}).String())
		}
	} else if kind == token.KindTag {
		tagName, value := line.Tag()
		var hit bool
		if tagName == "EXT-X-KEY" {
			hit = true
		}
		if hit {
			attrs := value.Attributes()
			uriValue, ok := attrs["URI"]
			if ok {
				uri := uriValue.FromString()
				if uri != "" && !strings.HasPrefix(uri, "http") { // 需要转绝对地址
					absoluteURL := r.baseURL.ResolveReference(&url.URL{Path: uri}).String()
					attrs["URI"] = token.AttributeValue(strconv.Quote(absoluteURL))
					line = token.NewLineTag(tagName, token.NewTagValueAttributes(attrs))
				}
			}
		}
	}
	r.buf = append(r.buf, line...)
	r.buf = append(r.buf, '\n')
	return r.Read(p)
}
